package com.xdcplus.web.service.wip.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.github.pagehelper.PageInfo;
import com.xdcplus.core.utils.BeanUtils;
import com.xdcplus.exceptions.XdcWebException;
import com.xdcplus.exceptions.domain.ResponseVO;
import com.xdcplus.mom.constants.NumberConstant;
import com.xdcplus.mom.constants.RequestConstant;
import com.xdcplus.mom.enums.ResponseEnum;
import com.xdcplus.mom.utils.AuthUtils;
import com.xdcplus.mp.service.impl.BaseServiceImpl;
import com.xdcplus.mp.utils.PageableUtils;
import com.xdcplus.mp.utils.PropertyUtils;
import com.xdcplus.pager.vo.PageVO;
import com.xdcplus.system.api.SysEncodeRuleRemote;
import com.xdcplus.system.api.dto.GenEncodeDTO;
import com.xdcplus.thirdparty.api.SiliconInspectionPipelineRemote;
import com.xdcplus.thirdparty.api.dto.CancelSyncUnpackPlanDto;
import com.xdcplus.thirdparty.api.dto.SyncUnpackPlanDto;
import com.xdcplus.web.common.enums.BdOpeEnum;
import com.xdcplus.web.common.enums.wip.MarkingStatusEnum;
import com.xdcplus.web.common.enums.wip.MarkingTypeEnum;
import com.xdcplus.web.common.pojo.dto.wip.*;
import com.xdcplus.web.common.pojo.entity.pm.PmWo;
import com.xdcplus.web.common.pojo.entity.tool.ToolInfo;
import com.xdcplus.web.common.pojo.entity.wip.*;
import com.xdcplus.web.common.enums.wip.WipUnPackCommandStatusEnum;
import com.xdcplus.web.common.pojo.query.wip.WipUnpackPlanQuery;
import com.xdcplus.web.common.pojo.vo.bd.BdMaterialVO;
import com.xdcplus.web.common.pojo.vo.pm.GetPmNowShiftVo;
import com.xdcplus.web.common.pojo.vo.pm.PmWoVO;
import com.xdcplus.web.common.pojo.vo.splitunpack.GetUnpackPlanByToolCodeVo;
import com.xdcplus.web.common.pojo.vo.wip.*;
import com.xdcplus.web.common.utils.PackDateUtils;
import com.xdcplus.web.mapper.pm.PmWoMapper;
import com.xdcplus.web.mapper.tool.ToolInfoMapper;
import com.xdcplus.web.mapper.wip.WipUnpackPlanMapper;
import com.xdcplus.web.mapper.wip.WipUnpackToolMapper;
import com.xdcplus.web.service.bd.BdMaterialService;
import com.xdcplus.web.service.pm.PmShiftManageService;
import com.xdcplus.web.service.pm.PmWoService;
import com.xdcplus.web.service.tool.ToolInfoService;
import com.xdcplus.web.service.wip.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Timestamp;
import java.time.Instant;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 投料/拆包计划表(WipUnpackPlan)表服务实现类
 *
 * @author xyy
 * @since 2023-05-04 19:55:25
 */
@Slf4j
@Service("wipUnpackPlanService")
public class WipUnpackPlanServiceImpl extends BaseServiceImpl<WipUnpackPlanMapper, WipUnpackPlan, WipUnpackPlan, WipUnpackPlanVO> implements WipUnpackPlanService {

    @Autowired
    protected WipUnpackPlanMapper wipUnpackPlanMapper;

    @Autowired
    protected PmWoMapper pmWoMapper;

    @Autowired
    protected ToolInfoMapper toolInfoMapper;

    @Autowired
    protected WipUnpackBoxService wipUnpackBoxService;

    @Autowired
    protected WipUnpackRawMaterialService wipUnpackRawMaterialService;

    @Autowired
    private PmWoService pmWoService;

    @Autowired
    protected WipUnpackToolService wipUnpackToolService;

    @Autowired
    protected WipUnpackToolMapper wipUnpackToolMapper;

    @Autowired
    protected SysEncodeRuleRemote sysEncodeRuleRemote;

    @Autowired
    private SiliconInspectionPipelineRemote siliconInspectionPipelineRemote;

    @Autowired
    private BdMaterialService bdMaterialService;

    @Autowired
    private PmShiftManageService pmShiftManageService;

    @Autowired
    private ToolInfoService toolInfoService;

    @Autowired
    protected WipMarkingReminderService wipMarkingReminderService;

    @Autowired
    protected WipMarkingService wipMarkingService;

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public WipUnpackPlan saveWipUnpackPlan(WipUnpackPlanDTO wipUnpackPlanDTO) {
        validWipUnpackPlan(wipUnpackPlanDTO);
        WipUnpackPlan wipUnpackPlan = new WipUnpackPlan();

        BeanUtil.copyProperties(wipUnpackPlanDTO, wipUnpackPlan);
        log.info("saveWipUnpackPlan wipUnpackPlanDTO: {}",wipUnpackPlanDTO.getCreatedUser());

        wipUnpackPlan.setCreatedUser(wipUnpackPlanDTO.getCreatedUser());

        if (CollectionUtil.isNotEmpty(wipUnpackPlanDTO.getReminders())) {
            String remindersStr = wipUnpackPlanDTO.getReminders().stream()
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));
            wipUnpackPlan.setReminders(remindersStr);
        }
        wipUnpackPlan.setCommandStatus(WipUnPackCommandStatusEnum.N.getCode());
        wipUnpackPlan.setCreatedTime(new Timestamp(DateUtil.current()));
        wipUnpackPlan.setDismantledCount(wipUnpackPlan.getPlannedQuantity());
        wipUnpackPlan.setTakenApartCount(0L);

        GenEncodeDTO genEncodeDTO = new GenEncodeDTO();
        genEncodeDTO.setNumber(1L);

        if (ObjectUtil.equals(wipUnpackPlanDTO.getMarkType(), MarkingTypeEnum.PRODUCTION_ORDER.getCode())) {
            genEncodeDTO.setRuleCode(RequestConstant.RULE_UNPACK_PRODUCE_CODE);
        } else if (ObjectUtil.equals(wipUnpackPlanDTO.getMarkType(), MarkingTypeEnum.REWORK_ORDER.getCode())) {
            genEncodeDTO.setRuleCode(RequestConstant.RULE_UNPACK_REWORK_CODE);
        } else {
            genEncodeDTO.setRuleCode(RequestConstant.RULE_UNPACK_EXPERIMENT_CODE);
        }
        ResponseVO<List<String>> listResponseVO = sysEncodeRuleRemote.genEncode(genEncodeDTO);
        wipUnpackPlan.setPlanCode(listResponseVO.getData().get(0));

        this.save(wipUnpackPlan);

        /// 拆包机台
        List<WipUnpackTool> wipUnpackTools = wipUnpackPlanDTO.getToolCodes().stream()
                .map(toolCode -> {
                    WipUnpackTool wipUnpackTool = new WipUnpackTool();
                    wipUnpackTool.setToolCode(toolCode);
                    wipUnpackTool.setWipUnpackPlanIdFk(wipUnpackPlan.getId());
                    wipUnpackTool.setCreatedUser(AuthUtils.getCurrentUser());
                    wipUnpackTool.setCreatedTime(Timestamp.from(Instant.now()));
                    return wipUnpackTool;
                }).collect(Collectors.toList());

        wipUnpackToolService.saveBatch(wipUnpackTools);

        return wipUnpackPlan;
    }


    private void validWipUnpackPlan(WipUnpackPlanDTO wipUnpackPlanDTO) {
        /// 工单数量和拆包计划数量
        PmWoVO pmWoVoByWoCode = pmWoService.getPmWoVoByWoCode(wipUnpackPlanDTO.getWoCode());
        if (ObjectUtil.isEmpty(pmWoVoByWoCode)) {
            throw new XdcWebException(ResponseEnum.PM_WO_NOT_EXISTS);
        }
        if (pmWoVoByWoCode.getAdtPrdQty() - pmWoVoByWoCode.getRlPrdQty() < wipUnpackPlanDTO.getPlannedQuantity()) {
            throw new XdcWebException(ResponseEnum.PLAN_OUT_OF_WO);
        }
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean updateWipUnpackPlan(WipUnpackPlanDTO wipUnpackPlanDTO) {

        WipUnpackPlan wipUnpackPlan = this.getById(wipUnpackPlanDTO.getId());
        if (ObjectUtil.isNull(wipUnpackPlan)) {
            log.error("updateWipUnpackPlan() The WipUnpackPlan does not exist or has been deleted");
            throw new XdcWebException(ResponseEnum.ERROR);
        }

        if (WipUnPackCommandStatusEnum.Y.getCode().equals(wipUnpackPlan.getCommandStatus())) {
            throw new XdcWebException(ResponseEnum.THE_UNPACK_COMMAND_STATUS);
        }

        BeanUtil.copyProperties(wipUnpackPlanDTO, wipUnpackPlan);
        wipUnpackPlan.setDismantledCount(wipUnpackPlan.getPlannedQuantity());
        wipUnpackPlan.setUpdatedUser(wipUnpackPlanDTO.getUpdatedUser());
        wipUnpackPlan.setUpdatedTime(new Timestamp(DateUtil.current()));


        LambdaQueryWrapper<WipUnpackTool> wipUnpackToolLambdaQueryWrapper = new LambdaQueryWrapper<>();
        wipUnpackToolLambdaQueryWrapper.eq(WipUnpackTool::getWipUnpackPlanIdFk, wipUnpackPlan.getId());
        wipUnpackToolMapper.delete(wipUnpackToolLambdaQueryWrapper);

        /// 拆包机台
        List<WipUnpackTool> wipUnpackTools = wipUnpackPlanDTO.getToolCodes().stream()
                .map(toolCode -> {
                    WipUnpackTool wipUnpackTool = new WipUnpackTool();
                    wipUnpackTool.setToolCode(toolCode);
                    wipUnpackTool.setWipUnpackPlanIdFk(wipUnpackPlan.getId());
                    wipUnpackTool.setCreatedUser(AuthUtils.getCurrentUser());
                    wipUnpackTool.setCreatedTime(Timestamp.from(Instant.now()));
                    return wipUnpackTool;
                }).collect(Collectors.toList());
        wipUnpackToolService.saveBatch(wipUnpackTools);
        return this.updateById(wipUnpackPlan);

    }

    @Override
    public Boolean saveOrUpdateBatch(List<WipUnpackPlan> wipUnpackPlanList) {

        wipUnpackPlanList.forEach(wipUnpackPlan -> {
            WipUnpackPlan wipUnpackPlanParam = new WipUnpackPlan();
            wipUnpackPlanParam.setId(wipUnpackPlan.getId());
            if (ObjectUtil.isNotNull(wipUnpackPlan.getId())) {
                wipUnpackPlan.setId(wipUnpackPlan.getId());
                wipUnpackPlan.setUpdatedTime(new Timestamp(DateUtil.current()));
                LambdaUpdateWrapper<WipUnpackPlan> lambdaUpdate = Wrappers.lambdaUpdate();
                lambdaUpdate.eq(WipUnpackPlan::getId, wipUnpackPlan.getId());
                update(wipUnpackPlan, lambdaUpdate);
            } else {
                wipUnpackPlan.setCreatedTime(new Timestamp(DateUtil.current()));
                save(wipUnpackPlan);
            }
        });
        return true;
    }

    @Override
    public Boolean saveOrUpdateBatchByDTOList(List<WipUnpackPlanDTO> wipUnpackPlanDTOList) {

        List<WipUnpackPlan> wipUnpackPlanList = BeanUtils.copyProperties(wipUnpackPlanDTOList, WipUnpackPlan.class);
        return saveOrUpdateBatch(wipUnpackPlanList);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean deleteWipUnpackPlanLogical(Long id) {

        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        WipUnpackPlan wipUnpackPlan = this.getById(id);

        if (ObjectUtil.isNull(wipUnpackPlan)) {
            log.error("deleteWipUnpackPlan() The WipUnpackPlan does not exist or has been deleted");
            throw new XdcWebException(ResponseEnum.ERROR);
        }
        if (WipUnPackCommandStatusEnum.Y.getCode().equals(wipUnpackPlan.getCommandStatus())) {
            throw new XdcWebException(ResponseEnum.THE_UNPACK_COMMAND_STATUS);
        }
        return this.removeById(id);
    }

    @Override
    @Transactional
    public void cancelWipUnpackPlan(Long id, String updatedUser) {
        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());
        WipUnpackPlan wipUnpackPlan = this.getById(id);
        Assert.notNull(wipUnpackPlan, "拆包计划不能为空");
        if (!WipUnPackCommandStatusEnum.Y.getCode().equals(wipUnpackPlan.getCommandStatus())) {
            throw new XdcWebException(ResponseEnum.ERROR, "下发状态不正确，无法取消");
        }
        wipUnpackPlan.setCommandStatus(WipUnPackCommandStatusEnum.CANCEL.getCode());
        wipUnpackPlan.setUpdatedUser(updatedUser);
        wipUnpackPlan.setUpdatedTime(new Timestamp(DateUtil.current()));
        this.updateById(wipUnpackPlan);
        //下发取消拆包任务
        CancelSyncUnpackPlanDto cancelSyncUnpackPlanDto = new CancelSyncUnpackPlanDto();
        cancelSyncUnpackPlanDto.setPlanCode(wipUnpackPlan.getPlanCode());
        siliconInspectionPipelineRemote.cancelSyncUnpackPlan(cancelSyncUnpackPlanDto);
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public Boolean deleteWipUnpackPlanByIds(String ids) {
        Assert.notNull(ids, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());
        List<String> idList = Arrays.asList(ids.split(","));
        if (CollectionUtil.isEmpty(idList)) {
            throw new XdcWebException(ResponseEnum.ERROR);
        }
        idList.forEach(id -> {
            WipUnpackPlan wipUnpackPlan = this.getById(id);
            if (ObjectUtil.isNull(wipUnpackPlan)) {
                log.error("deleteWipUnpackPlan() The WipUnpackPlan does not exist or has been deleted");
                throw new XdcWebException(ResponseEnum.ERROR);
            }
        });

        return this.removeByIds(idList);
    }

    private List<WipUnpackPlan> queryWipUnpackPlanList(WipUnpackPlanFilterDTO wipUnpackPlanFilterDTO) {
        WipUnpackPlanQuery wipUnpackPlanQuery = BeanUtil.copyProperties(wipUnpackPlanFilterDTO, WipUnpackPlanQuery.class);

        return wipUnpackPlanMapper.queryWipUnpackPlan(wipUnpackPlanQuery);
    }

    @Override
    public List<WipUnpackPlanVO> queryWipUnpackPlanVOList(WipUnpackPlanFilterDTO wipUnpackPlanFilterDTO) {
        return this.objectConversion(queryWipUnpackPlanList(wipUnpackPlanFilterDTO));
    }

    @Override
    public PageVO<WipUnpackPlanVO> queryWipUnpackPlan(WipUnpackPlanFilterDTO wipUnpackPlanFilterDTO) {
        String endDate = PackDateUtils.getAddDate(wipUnpackPlanFilterDTO.getEndDate(), 1);
        if (StringUtils.isNotBlank(endDate)) {
            wipUnpackPlanFilterDTO.setEndDate(endDate);
        }
        PageVO<WipUnpackPlanVO> pageVO = new PageVO<>();
        if (wipUnpackPlanFilterDTO.getCurrentPage() > NumberConstant.ZERO) {
            PageableUtils.basicPage(wipUnpackPlanFilterDTO.getCurrentPage(), wipUnpackPlanFilterDTO.getPageSize(),
                    "DESC", "CREATED_TIME");
        }

        List<WipUnpackPlan> wipUnpackPlanList = queryWipUnpackPlanList(wipUnpackPlanFilterDTO);
        List<WipUnpackPlanVO> wipUnpackPlanVOList = this.objectConversion(wipUnpackPlanList);

        if (CollectionUtil.isNotEmpty(wipUnpackPlanVOList)) {
            //通过工单id获取产品编号
            List<String> woCodeList = wipUnpackPlanVOList.stream().map(WipUnpackPlanVO::getWoCode).collect(Collectors.toList());
            List<UpPackProductVO> upPackProductVOList = pmWoMapper.queryByWoCodes(woCodeList);
            Assert.notNull(upPackProductVOList, "获取工单失败");
            Map<String, UpPackProductVO> upPackProductVOMap = upPackProductVOList.stream().collect(Collectors.toMap(UpPackProductVO::getWoCode, upPackProductVO -> upPackProductVO));


            Set<String> toolCodeList = new HashSet<>();
            Map<Long, List<WipUnpackTool>> unpackToolMap = new HashMap<>();
            List<Long> planIdList = wipUnpackPlanVOList.stream().map(WipUnpackPlanVO::getId).distinct().collect(Collectors.toList());
            if (ObjectUtil.isNotEmpty(planIdList)) {
                LambdaQueryWrapper<WipUnpackTool> wipUnpackToolLambdaQueryWrapper = new LambdaQueryWrapper<>();
                wipUnpackToolLambdaQueryWrapper.in(WipUnpackTool::getWipUnpackPlanIdFk, planIdList);

                List<WipUnpackTool> list = wipUnpackToolService.list(wipUnpackToolLambdaQueryWrapper);

                toolCodeList.addAll(list.stream().map(WipUnpackTool::getToolCode).collect(Collectors.toSet()));

                unpackToolMap = list.stream()
                        .collect(Collectors.groupingBy(WipUnpackTool::getWipUnpackPlanIdFk));
            }

            //通过设备编号获取设备名称
            Map<String, String> toolInfoMap = new HashMap<>();
            if (ObjectUtil.isNotEmpty(toolCodeList)) {
                List<ToolInfo> toolInfoList = toolInfoMapper.queryToolInfoByToolCodes(new ArrayList<>(toolCodeList));
                toolInfoMap = toolInfoList.stream().collect(Collectors.toMap(ToolInfo::getToolCode, ToolInfo::getToolName));
            }

            Map<Long, List<WipUnpackTool>> finalUnpackToolMap = unpackToolMap;
            Map<String, String> finalToolInfoMap = toolInfoMap;
            wipUnpackPlanVOList.forEach(wipUnpackPlanVO -> {
                String woCode = wipUnpackPlanVO.getWoCode();
//                String toolCode = wipUnpackPlanVO.getToolCode();
                String commandStatus = wipUnpackPlanVO.getCommandStatus();
                if (upPackProductVOMap.containsKey(woCode)) {
                    wipUnpackPlanVO.setMaterialName(upPackProductVOMap.get(woCode).getMaterialName());
                    wipUnpackPlanVO.setMaterialCode(upPackProductVOMap.get(woCode).getMaterialCode());
                    wipUnpackPlanVO.setWoCate(upPackProductVOMap.get(woCode).getWoCate());
                }
                //修改后
                wipUnpackPlanVO.setCommandStatusDesc(WipUnPackCommandStatusEnum.getMsgByCode(commandStatus));
//                if (toolInfoMap.containsKey(toolCode)) {
//                    wipUnpackPlanVO.setToolName(toolInfoMap.get(toolCode));
//                }
                if (wipUnpackPlanVO.getPmShiftPlanIdFk() != null) {
                    wipUnpackPlanVO.setPmShiftPlanName(pmShiftManageService.getShiftNameById(wipUnpackPlanVO.getPmShiftPlanIdFk()));
                }

                /// 拼接机台信息，多选
                if (ObjectUtil.isNotNull(finalUnpackToolMap) && ObjectUtil.isNotEmpty(finalUnpackToolMap.get(wipUnpackPlanVO.getId()))) {
                    List<String> toolCodes = finalUnpackToolMap.get(wipUnpackPlanVO.getId()).stream().map(WipUnpackTool::getToolCode).collect(Collectors.toList());
                    wipUnpackPlanVO.setToolCodes(toolCodes);

                    if (ObjectUtil.isNotNull(finalToolInfoMap)) {
                        wipUnpackPlanVO.setToolNames(toolCodes.stream().map(
                                finalToolInfoMap::get
                        ).collect(Collectors.toList()));
                    }
                }

            });
        }

        PageInfo<WipUnpackPlan> pageInfo = new PageInfo<>(wipUnpackPlanList);
        PropertyUtils.copyProperties(pageInfo, pageVO, wipUnpackPlanVOList);

        return pageVO;
    }

    @Override
    public WipUnpackPlanVO queryWipUnpackPlanById(Long id) {

        Assert.notNull(id, ResponseEnum.THE_ID_CANNOT_BE_EMPTY.getMessage());

        return this.objectConversion(this.getById(id));
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void commandWipUnpackPlan(List<Long> ids, String username) {
        Assert.notNull(ids, "下达的计划的任务id不能为空");
        List<WipUnpackPlan> wipUnpackPlanList = wipUnpackPlanMapper.selectBatchIds(ids);
        Assert.notNull(wipUnpackPlanList, "获取下达指令的计划失败");

        /// 判定计划状态，是否为未下达
        if (wipUnpackPlanList.stream().filter(wipUnpackPlan -> !WipUnPackCommandStatusEnum.N.getCode().equals(wipUnpackPlan.getCommandStatus())).count() > 0) {
            throw new XdcWebException(ResponseEnum.UNPACK_PLAN_STATUS_ERROR);
        }

        List<WipUnpackPlan> wipUnpackPlanList1 = new ArrayList<>();
        wipUnpackPlanList.forEach(wipUnpackPlan -> {
            wipUnpackPlan.setCommandStatus(WipUnPackCommandStatusEnum.Y.getCode());
            wipUnpackPlan.setUpdatedUser(username);
            wipUnpackPlan.setUpdatedTime(new Timestamp(DateUtil.current()));
            wipUnpackPlanList1.add(wipUnpackPlan);
        });
        this.updateBatchById(wipUnpackPlanList1);
        for (WipUnpackPlan wipUnpackPlan : wipUnpackPlanList1) {
            List<WipUnpackTool> wipUnpackToolList = wipUnpackToolService.findByWipUnpackPlanIdFk(wipUnpackPlan.getId());
            if (CollectionUtil.isNotEmpty(wipUnpackToolList)) {
                String toolCodes = wipUnpackToolList.stream()
                        .map(WipUnpackTool::getToolCode)
                        .collect(Collectors.joining(","));
                PmWo pmWo = pmWoService.getPmWoById(wipUnpackPlan.getPmWoFkId());
                Assert.notNull(pmWo, "工单不存在");
                BdMaterialVO bdMaterialVO = bdMaterialService.queryBdMaterialById(pmWo.getProductIdFk());
                SyncUnpackPlanDto syncUnpackPlanDto = new SyncUnpackPlanDto();
                syncUnpackPlanDto.setPlanCode(wipUnpackPlan.getPlanCode());
                syncUnpackPlanDto.setPlanQuantity(wipUnpackPlan.getPlannedQuantity());
                syncUnpackPlanDto.setToolCodes(toolCodes);
                syncUnpackPlanDto.setBoxCodeQuantity(wipUnpackPlan.getMagazineCapacity());
                syncUnpackPlanDto.setCheckBatchNo(wipUnpackPlan.getSuppliedBatch());
                syncUnpackPlanDto.setMaterialCode(bdMaterialVO.getMaterialCode());
                siliconInspectionPipelineRemote.syncUnpackPlan(syncUnpackPlanDto);
            }

            if (ObjectUtil.equals(wipUnpackPlan.getMarkType(), MarkingTypeEnum.EXPERIMENTAL_ORDER_MIXABLE.getCode())||
                    ObjectUtil.equals(wipUnpackPlan.getMarkType(), MarkingTypeEnum.EXPERIMENTAL_ORDER_NON_MIXABLE.getCode())) {
                // 同步工艺实验记录
                WipMarking wipMarking = BeanUtil.copyProperties(wipUnpackPlan, WipMarking.class,"id");
                wipMarking.setWoCode(wipUnpackPlan.getWoCode());
                wipMarking.setMarkCode(wipUnpackPlan.getPlanCode());
                wipMarking.setMarkTypeCode(wipUnpackPlan.getMarkType());
                wipMarking.setStartOpeCode(BdOpeEnum.FPCB_OPE.getCode());
                wipMarking.setWarnOpeCodes(wipUnpackPlan.getWarnOpeCodes());
                wipMarking.setMarkCreatedType(1);
                wipMarkingService.save(wipMarking);

                /// 提醒人
                List<WipMarkingReminder> wipMarkingReminders = Arrays.stream(wipUnpackPlan.getReminders().split(",")).map(reminder -> {
                    WipMarkingReminder wipMarkingReminder = new WipMarkingReminder();
                    wipMarkingReminder.setMarkingIdFk(wipMarking.getId());
                    wipMarkingReminder.setMarkCode(wipMarking.getMarkCode());
                    wipMarkingReminder.setUserId(Long.valueOf(reminder));
                    return wipMarkingReminder;
                }).collect(Collectors.toList());
                wipMarkingReminderService.saveBatch(wipMarkingReminders);
            }
        }

    }

    @Override
    public UnPackMaterialDetailVO findMaterialDetailInfo(Long id) {
        WipUnpackPlan wipUnpackPlan = this.getById(id);
        Assert.notNull(wipUnpackPlan, "获取拆包信息失败");
        ToolInfo toolInfo = toolInfoMapper.queryToolInfoByToolCode(wipUnpackPlan.getToolCode());
        Assert.notNull(toolInfo, "获取设备信息失败");
        WipUnpackBoxFilterDTO wipUnpackBoxFilterDTO = new WipUnpackBoxFilterDTO();
        wipUnpackBoxFilterDTO.setWipUnpackPlanIdFk(id);
        List<WipUnpackBoxVO> wipUnpackBoxVOList = wipUnpackBoxService.queryWipUnpackBoxVOList(wipUnpackBoxFilterDTO);
        WipUnpackRawMaterialFilterDTO wipUnpackRawMaterialFilterDTO = new WipUnpackRawMaterialFilterDTO();
//        wipUnpackRawMaterialFilterDTO.setPmUnpackPlanIdFk(id);
        List<WipUnpackRawMaterialVO> wipUnpackRawMaterialVOList = wipUnpackRawMaterialService.queryWipUnpackRawMaterialVOList(wipUnpackRawMaterialFilterDTO);

        wipUnpackRawMaterialVOList.forEach(wipUnpackRawMaterialVO -> {
//            wipUnpackRawMaterialVO.setToolCode(toolInfo.getToolName());
            wipUnpackRawMaterialVO.setToolCode(wipUnpackPlan.getToolCode());
        });
        UnPackMaterialDetailVO unPackMaterialDetailVO = new UnPackMaterialDetailVO();
        unPackMaterialDetailVO.setWipUnpackBoxVOS(new ArrayList<>());
        unPackMaterialDetailVO.setWipUnpackRawMaterialVOS(new ArrayList<>());
        unPackMaterialDetailVO.getWipUnpackBoxVOS().addAll(wipUnpackBoxVOList);
        unPackMaterialDetailVO.getWipUnpackRawMaterialVOS().addAll(wipUnpackRawMaterialVOList);
        return unPackMaterialDetailVO;
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public void bindMaterialBox(WipUnpackBindMaterialDTO wipUnpackBindMaterialDTO, String username) {

        List<WipUnpackBoxDTO> wipUnpackBoxDTOList = wipUnpackBindMaterialDTO.getWipUnpackBoxDTOList();
        List<WipUnpackRawMaterialDTO> wipUnpackRawMaterialDTOList = wipUnpackBindMaterialDTO.getWipUnpackRawMaterialDTOList();
        if (CollectionUtil.isEmpty(wipUnpackBoxDTOList) && CollectionUtil.isEmpty(wipUnpackRawMaterialDTOList)) {
            throw new XdcWebException(ResponseEnum.THE_UNPACK_BIND_BOX_NOT_EMPTY);
        }

        if (CollectionUtil.isNotEmpty(wipUnpackBoxDTOList)) {
            List<WipUnpackBox> wipUnpackBoxList = BeanUtils.copyProperties(wipUnpackBoxDTOList, WipUnpackBox.class);
            wipUnpackBoxList.forEach(wipUnpackBox -> {
                wipUnpackBox.setWipUnpackPlanIdFk(wipUnpackBindMaterialDTO.getId());
                wipUnpackBox.setCreatedUser(username);
                wipUnpackBox.setCreatedUser(username);
                wipUnpackBox.setUpdatedTime(new Timestamp(DateUtil.current()));
            });
            wipUnpackBoxService.saveOrUpdateBatch(wipUnpackBoxList);

        }
        if (CollectionUtil.isNotEmpty(wipUnpackRawMaterialDTOList)) {
            List<WipUnpackRawMaterial> wipUnpackRawMaterialList = BeanUtils.copyProperties(wipUnpackRawMaterialDTOList, WipUnpackRawMaterial.class);
            wipUnpackRawMaterialList.forEach(wipUnpackRawMaterial -> {
//                wipUnpackRawMaterial.setPmUnpackPlanIdFk(wipUnpackBindMaterialDTO.getId());
                wipUnpackRawMaterial.setCreatedUser(username);
                wipUnpackRawMaterial.setCreatedUser(username);
                wipUnpackRawMaterial.setUpdatedTime(new Timestamp(DateUtil.current()));
            });
            wipUnpackRawMaterialService.saveOrUpdateBatch(wipUnpackRawMaterialList);
        }

    }

    @Override
    public void updateMaterialCount(WipUpPackUpdateCountDTO wipUpPackUpdateCountDTO, String username) {
        WipUnpackPlan wipUnpackPlan = this.getById(wipUpPackUpdateCountDTO.getId());
        Assert.notNull(wipUnpackPlan, "获取拆包信息失败");
        wipUnpackPlan.setUpdatedTime(new Timestamp(DateUtil.current()));
        wipUnpackPlan.setUpdatedUser(username);
        wipUnpackPlan.setDismantledCount(wipUpPackUpdateCountDTO.getDismantledCount());
        wipUnpackPlan.setTakenApartCount(wipUpPackUpdateCountDTO.getTakenApartCount());
        this.updateById(wipUnpackPlan);
    }

    @Override
    public WipUnpackPlan getUnpackPlanByProcess(String commissioningDate, Long pmShiftPlanIdFk, String toolCode) {
        return wipUnpackPlanMapper.getUnpackPlanByProcess(commissioningDate, pmShiftPlanIdFk, toolCode);
    }

    @Override
    public GetUnpackPlanByToolCodeVo getUnpackPlanByToolCode(String toolCode) {
        GetUnpackPlanByToolCodeVo getUnpackPlanByToolCodeVo = new GetUnpackPlanByToolCodeVo();
        Timestamp nowTime = new Timestamp(DateUtil.current());
        GetPmNowShiftVo getPmNowShiftVo = pmShiftManageService.getPmShiftByTimestamp(nowTime);
        Assert.notNull(getPmNowShiftVo, "排班计划未维护");
        WipUnpackPlan wipUnpackPlan = wipUnpackPlanMapper.getUnpackPlanByProcess(getPmNowShiftVo.getShiftDate(), getPmNowShiftVo.getPmShiftManageId(), toolCode);
        Assert.notNull(wipUnpackPlan, "拆包计划未维护");
        BeanUtil.copyProperties(wipUnpackPlan, getUnpackPlanByToolCodeVo);
        PmWo pmWo = pmWoService.getPmWoByWoCode(wipUnpackPlan.getWoCode());
        Assert.notNull(pmWo, "拆包计划的工单不存在");
        BdMaterialVO bdMaterialVO = bdMaterialService.queryBdMaterialById(pmWo.getProductIdFk());
        if (bdMaterialVO != null) {
            getUnpackPlanByToolCodeVo.setProductName(bdMaterialVO.getMaterialName());
        }
        getUnpackPlanByToolCodeVo.setPlanCode(wipUnpackPlan.getPlanCode());
        if (StringUtils.isNotBlank(getUnpackPlanByToolCodeVo.getToolCode())) {
            getUnpackPlanByToolCodeVo.setToolName(toolInfoService.getToolNameByToolCode(getUnpackPlanByToolCodeVo.getToolCode()));
        }
        return getUnpackPlanByToolCodeVo;
    }

    @Override
    public void canelWipUnpackPlan(List<Long> ids, String username) {
        Assert.notNull(ids, "下达的计划的任务id不能为空");
        List<WipUnpackPlan> wipUnpackPlanList = wipUnpackPlanMapper.selectBatchIds(ids);
        Assert.notNull(wipUnpackPlanList, "获取下达指令的计划失败");

        List<WipUnpackPlan> wipUnpackPlanList1 = new ArrayList<>();
        wipUnpackPlanList.forEach(wipUnpackPlan -> {
            if (!WipUnPackCommandStatusEnum.E.getCode()
                    .equals(wipUnpackPlan.getCommandStatus())) {
                wipUnpackPlan.setCommandStatus(WipUnPackCommandStatusEnum.E.getCode());
                wipUnpackPlan.setUpdatedUser(username);
                wipUnpackPlan.setUpdatedTime(new Timestamp(DateUtil.current()));
                wipUnpackPlanList1.add(wipUnpackPlan);
            }
        });
        this.updateBatchById(wipUnpackPlanList1);

        for (WipUnpackPlan wipUnpackPlan : wipUnpackPlanList1) {
            //下发取消拆包任务
            CancelSyncUnpackPlanDto cancelSyncUnpackPlanDto = new CancelSyncUnpackPlanDto();
            cancelSyncUnpackPlanDto.setPlanCode(wipUnpackPlan.getPlanCode());
            siliconInspectionPipelineRemote.cancelSyncUnpackPlan(cancelSyncUnpackPlanDto);

            if (ObjectUtil.equals(MarkingTypeEnum.EXPERIMENTAL_ORDER_MIXABLE.getCode(), wipUnpackPlan.getMarkType())||
                    ObjectUtil.equals(MarkingTypeEnum.EXPERIMENTAL_ORDER_NON_MIXABLE.getCode(), wipUnpackPlan.getMarkType())) {
                // 更新工艺实验片的状态
                LambdaUpdateWrapper<WipMarking> wipMarkingLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
                wipMarkingLambdaUpdateWrapper.eq(WipMarking::getMarkCode,wipUnpackPlan.getPlanCode());
                wipMarkingLambdaUpdateWrapper.set(WipMarking::getMarkStatus, MarkingStatusEnum.STOP.getCode());
                wipMarkingService.update(wipMarkingLambdaUpdateWrapper);
            }
        }

    }

    @Override
    public void deleteBatchWipUnpackPlanLogical(List<Long> wipUnpackPlanIds) {
        LambdaQueryWrapper<WipUnpackPlan> wipUnpackPlanLambdaQueryWrapper = new LambdaQueryWrapper<>();
        wipUnpackPlanLambdaQueryWrapper.in(WipUnpackPlan::getId, wipUnpackPlanIds);
        wipUnpackPlanLambdaQueryWrapper.eq(WipUnpackPlan::getCommandStatus, WipUnPackCommandStatusEnum.N.getCode());
        baseMapper.delete(wipUnpackPlanLambdaQueryWrapper);
    }

    @Override
    public WipUnpackPlan getUnpackPlanByPlanCode(String planCode) {
        return wipUnpackPlanMapper.getUnpackPlanByPlanCode(planCode);
    }

    @Override
    public List<WipUnpackPlan> getUnpackPlanByPlanCodes(List<String> unpackPlanCodes) {
        return baseMapper.getUnpackPlanByPlanCodes(unpackPlanCodes);
    }


}
